home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / toswinsc.zoo / util.c < prev    next >
C/C++ Source or Header  |  1992-10-27  |  20KB  |  892 lines

  1. /*
  2.  * Copyright 1992 Eric R. Smith. All rights reserved.
  3.  * Redistribution is permitted only if the distribution
  4.  * is not for profit, and only if all documentation
  5.  * (including, in particular, the file "copying")
  6.  * is included in the distribution in unmodified form.
  7.  * THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
  8.  * EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
  9.  * FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
  10.  * RISK.
  11.  */
  12. #include "xgem.h"
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include "toswin.h"
  16. #include "twdefs.h"
  17. #include "twproto.h"
  18.  
  19. extern char *read_scrap();
  20. extern void write_scrap();
  21.  
  22. /* shift key states */
  23. #define KLSHIFT    0x1
  24. #define KRSHIFT    0x2
  25. #define KCTRL    0x4
  26. #define KALT    0x8
  27. #define KANY    (0xf)
  28.  
  29. /* what to add at the end of lines */
  30. #define CR    1
  31. #define LF    2
  32. #define CRLF    3
  33. #ifdef NONE
  34. #undef NONE
  35. #endif
  36.  
  37. #define NONE    0
  38. int paste_options = CR;
  39.  
  40. /* how to cut lines */
  41. #define STRIPBLANKS    1
  42. #define OBEYLINES    2
  43. int cut_options = STRIPBLANKS;
  44.  
  45.  
  46. void
  47. setcutoptions()
  48. {
  49.     int xclip, yclip, wclip, hclip;
  50.     int ret;
  51.  
  52.     cutdialog[ADDCRLF].ob_state = 
  53.     cutdialog[ADDLF].ob_state =
  54.     cutdialog[ADDCR].ob_state = 
  55.     cutdialog[ADDNONE].ob_state = NORMAL;
  56.  
  57.     switch(paste_options) {
  58.     case CR:
  59.         ret = ADDCR; break;
  60.     case LF:
  61.         ret = ADDLF; break;
  62.     case CRLF:
  63.         ret = ADDCRLF; break;
  64.     default:
  65.         ret = NONE; break;
  66.     }
  67.     cutdialog[ret].ob_state = SELECTED;
  68.  
  69.     cutdialog[STRIPEOL].ob_state = (cut_options & STRIPBLANKS) ? SELECTED :
  70.             NORMAL;
  71.     cutdialog[OBEYEOL].ob_state = (cut_options & OBEYLINES) ? SELECTED :
  72.             NORMAL;
  73.  
  74.     wind_update(1);
  75.     form_center(cutdialog, &xclip, &yclip, &wclip, &hclip);
  76.     form_dial(FMD_START, 0, 0, 32, 32, xclip, yclip, wclip, hclip);
  77.     if (win_flourishes)
  78.         form_dial(FMD_GROW, 0, 0, 32, 32, xclip, yclip, wclip, hclip);
  79.     objc_draw(cutdialog, 0, 2, xclip, yclip, wclip, hclip);
  80.     ret = form_do(cutdialog,  0);
  81.     if (win_flourishes)
  82.         form_dial(FMD_SHRINK, 0, 0, 32, 32, xclip, yclip, wclip, hclip);
  83.     form_dial(FMD_FINISH, 0, 0, 32, 32, xclip, yclip, wclip, hclip);
  84.     wind_update(0);
  85.  
  86.     cutdialog[ret].ob_state = NORMAL;
  87.     if (ret == EDOK) {
  88.         cut_options = NONE;
  89.         if (cutdialog[STRIPEOL].ob_state == SELECTED)
  90.             cut_options |= STRIPBLANKS;
  91.         if (cutdialog[OBEYEOL].ob_state == SELECTED)
  92.             cut_options |= OBEYLINES;
  93.  
  94.         if (cutdialog[ADDCR].ob_state == SELECTED)
  95.             paste_options = CR;
  96.         else if (cutdialog[ADDLF].ob_state == SELECTED)
  97.             paste_options = LF;
  98.         else if (cutdialog[ADDCRLF].ob_state == SELECTED)
  99.             paste_options = CRLF;
  100.         else
  101.             paste_options = NONE;
  102.  
  103.     }
  104. }
  105.  
  106. /* unselect all text in the indicated window */
  107.  
  108. void
  109. unselect(t)
  110.     TEXTWIN *t;
  111. {
  112.     int i, j;
  113.  
  114.     for (i = 0; i < t->maxy; i++)
  115.         for (j = 0; j < t->maxx; j++) {
  116.             if (t->cflag[i][j] & CSELECTED) {
  117.                 t->cflag[i][j] &= ~CSELECTED;
  118.                 t->cflag[i][j] |= CTOUCHED;
  119.                 t->dirty[i] |= SOMEDIRTY;
  120.                 }
  121.         }
  122.     refresh_textwin(t);
  123. }
  124.  
  125. /* cut selected text from a window */
  126.  
  127. char *cliptext = 0;
  128.  
  129. void
  130. cut(w)
  131.     WINDOW *w;
  132. {
  133.     TEXTWIN *t;
  134.     int i, j, numchars, numlines;
  135.     int linedone;
  136.     int needcrlf;
  137.     char *s, c;
  138.  
  139.     if (w->wtype != TEXT_WIN) return;
  140.     t = w->extra;
  141.  
  142.     if (cliptext) {
  143.         free(cliptext);
  144.         cliptext = 0;
  145.     }
  146.  
  147.     numchars = numlines = 0;
  148.     for (i = 0; i < t->maxy; i++) {
  149.         linedone = 0;
  150.         for (j = 0; j < t->maxx; j++) {
  151.             if (t->cflag[i][j] & CSELECTED) {
  152.                 numchars++;
  153.                 if (!linedone) {
  154.                     numlines++;
  155.                     linedone = 1;
  156.                 }
  157.             }
  158.         }
  159.     }
  160.     if (!numchars) {
  161.         form_alert(1, AlertStrng(NOTEXT));
  162.         return;
  163.     }
  164. /*
  165.  * The cut strategy is a little complicated, but here it is:
  166.  * A "line" is a continuous stream of characters. If the "Obey Lines"
  167.  * option is set, lines always end at end-of-line; otherwise, they
  168.  * end at eol only if there are 2 or more spaces after them.
  169.  * If "Strip Blanks" is set, then any trailing blanks are deleted.
  170.  */
  171.     cliptext = malloc(numchars+numlines+numlines+1);
  172.     if (!cliptext) {
  173.         form_alert(1, AlertStrng(NOMEM));
  174.         return;
  175.     }
  176.  
  177.     s = cliptext;
  178.  
  179.     needcrlf = 0;
  180.     for (i = 0; i < t->maxy; i++) {
  181.         linedone = 0;
  182.         for (j = 0; j < t->maxx; j++) {
  183.             if (t->cflag[i][j] & CSELECTED) {
  184.                 c = t->data[i][j];
  185.                 if (!c) c = ' ';
  186.                 *s++ = c;
  187.                 needcrlf = 1;
  188.                 if ( (cut_options & OBEYLINES) ||
  189.                      (j < t->maxy-2) ||
  190.                      ((c == ' ') && t->data[i][j-1] == ' '))
  191.                     linedone = 1;
  192.                 else
  193.                     linedone = 0;
  194.             }
  195.         }
  196.         if (linedone) {
  197.             if (cut_options & STRIPBLANKS) {
  198.                 while (s > cliptext && s[-1] == ' ')
  199.                     --s;
  200.             }
  201.             *s++ = '\r'; *s++ = '\n';
  202.             needcrlf = 0;
  203.         }
  204.     }
  205.  
  206. /* tie off cliptext */
  207.     if (needcrlf) {
  208.         *s++ = '\r'; *s++ = '\n';
  209.     }
  210.     *s++ = 0;
  211.  
  212.     unselect(t);
  213. }
  214.  
  215. /* paste text into a window */
  216.  
  217. void
  218. paste(w)
  219.     WINDOW *w;
  220. {
  221.     char *s;
  222.     int c;
  223.  
  224.     if (!cliptext) {
  225.         form_alert(1, AlertStrng(NOCUT));
  226.         return;
  227.     }
  228.     for (s = cliptext; *s; s++) {
  229.         c = *(unsigned char *)s;
  230.         if (c == '\r' && s[1] == '\n') {
  231.             s++;
  232.             switch(paste_options) {
  233.             case CRLF:
  234.                 (*w->keyinp)(w, '\r', 0);
  235.             case LF:
  236.                 (*w->keyinp)(w, '\n', 0);
  237.                 break;
  238.             case CR:
  239.                 (*w->keyinp)(w, '\r', 0);
  240.                 break;
  241.             case NONE:
  242.                 break;
  243.             }
  244.         } else 
  245.             (*w->keyinp)(w, c, 0);
  246.     }
  247. }
  248.  
  249. void
  250. redraw_screen(x, y, w, h)
  251.     int x, y, w, h;
  252. {
  253.     form_dial(0, x, y, w, h, x, y, w, h);
  254.     form_dial(3, x, y, w, h, x, y, w, h);
  255. }
  256.  
  257. /* cut text from the desktop */
  258.  
  259. void
  260. cut_from_desk(x, y)
  261.     int x, y;
  262. {
  263.     int i;
  264.     int width, height, x1, y1, x2, y2, dummy;
  265.     WINDOW *w;
  266.  
  267.     i = objc_find(deskobj, 0, 1, x, y);
  268.     if (i != CLIPICN) {
  269.         if (gl_topwin && gl_topwin->wtype == TEXT_WIN)
  270.             unselect(gl_topwin->extra);
  271.         return;
  272.     }
  273.     width = deskobj[i].ob_width; height = deskobj[i].ob_height;
  274.     objc_offset(deskobj, i, &x1, &y1);
  275.  
  276. /* drag the icon around */
  277.     wind_update(BEG_MCTRL);
  278.     graf_mouse(FLAT_HAND, 0L);
  279.     graf_dragbox(width, height, x1, y1, xdesk, ydesk, wdesk, hdesk,
  280.         &x2, &y2);
  281.  
  282.     graf_mkstate(&x, &y, &dummy, &dummy);
  283.     graf_mouse(ARROW, 0L);
  284.     wind_update(END_MCTRL);
  285.  
  286. /* did we actually move anywhere? */
  287.     if (x >= x1 && x <= x1+width && y >= y1 && y <= y1+height) {
  288.         return;
  289.     }
  290.     w = find_window(x, y);
  291.     if (w && w->wtype == TEXT_WIN) {
  292.         if (cliptext)
  293.             free(cliptext);
  294.  
  295.         cliptext = read_scrap("SCRAP.TXT");
  296.         if (!cliptext) {
  297.             form_alert(1, AlertStrng(SCRAPDAT));
  298.             return;
  299.         }
  300.         paste(w);
  301. #if 0
  302.     } else {        /* just move the icon */
  303.         hide_mouse();
  304.         deskobj[i].ob_x += x2 - x1;
  305.         deskobj[i].ob_y += y2 - y1;
  306.         redraw_screen(x1, y1, width, height);
  307.         redraw_screen(x2, y2, width, height);
  308.         show_mouse();
  309. #endif
  310.     }
  311. }
  312.  
  313. /* paste text onto the desktop */
  314.  
  315. void
  316. paste_to_desk(x, y)
  317.     int x, y;
  318. {
  319.     int i;
  320.     int x1, y1;
  321.     WINDOW *w;
  322.  
  323.     w = find_window(x, y);
  324.     i = objc_find(deskobj, 0, 1, x, y);
  325.     if (i == CLIPICN) {
  326.         objc_offset(deskobj, CLIPICN, &x1, &y1);
  327.         objc_change(deskobj, CLIPICN, 0, xdesk, ydesk, wdesk, hdesk,
  328.             SELECTED, 0);
  329.         if (w == toolwindow) {
  330.             redraw_window(toolwindow, x1, y1,
  331.                 deskobj[i].ob_width, deskobj[i].ob_height);
  332.         }
  333.         write_scrap("SCRAP.TXT", cliptext, (int)strlen(cliptext));
  334.         objc_change(deskobj, CLIPICN, 0, xdesk, ydesk, wdesk, hdesk,
  335.             NORMAL, 0);
  336.         if (w == toolwindow) {
  337.             redraw_window(toolwindow, x1, y1,
  338.                 deskobj[i].ob_width, deskobj[i].ob_height);
  339.         }
  340.     }
  341. }
  342.  
  343. static void
  344. lightbox(plin, numpoints)
  345.     int *plin;
  346.     int numpoints;
  347. {
  348.     static int vtbl[4] = { 0x5555, 0xaaaa, 0xaaaa, 0x5555 };
  349.     static int htbl[2] = { 0x5555, 0xaaaa };
  350.     int style, *linexy, i;
  351.     int attrib[6];
  352.  
  353.     vql_attribute(vdi_handle, attrib);
  354.  
  355.     vsl_color(vdi_handle, 1);
  356.  
  357.     for (i = 1; i < numpoints; i++) {
  358.         if (plin[0] == plin[2])
  359.             style = vtbl[(plin[0] & 1) | ((plin[1] & 1) << 1)];
  360.         else {
  361.             linexy = (plin[0] < plin[2]) ? plin : plin+2;
  362.             style = htbl[ linexy[1] & 1 ];
  363.         }
  364.         vsl_udsty(vdi_handle, style);
  365.         vsl_type(vdi_handle, 7);
  366.         v_pline(vdi_handle, 2, plin);
  367.         plin += 2;
  368.     }
  369.  
  370.     vsl_type(vdi_handle, attrib[0]);
  371.     vsl_color(vdi_handle, attrib[1]);
  372. }
  373.  
  374. void
  375. hot_dragbox(plin, numpoints, lastx, lasty)
  376.     int *plin;
  377.     int numpoints;
  378.     int *lastx, *last